package controller

import (
	"net/http"
	"strconv"
	"time"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/auth"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

// PlatformSwitchController 平台切换控制器
type PlatformSwitchController struct {
	db                    *gorm.DB
	platformSwitchService *service.PlatformSwitchService
}

// NewPlatformSwitchController 创建平台切换控制器实例
func NewPlatformSwitchController() *PlatformSwitchController {
	return &PlatformSwitchController{
		db:                    database.DB,
		platformSwitchService: service.NewPlatformSwitchService(),
	}
}

// CheckSwitchConstraints 检查平台切换约束
// @Summary 检查平台切换约束
// @Description 检查用户是否可以切换平台，返回详细的约束信息
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} models.PlatformSwitchCheckResponse
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/platform/switch/check [get]
func (c *PlatformSwitchController) CheckSwitchConstraints(ctx *gin.Context) {
	// 获取当前用户ID
	claims, exists := ctx.Get("claims")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "invalid_token_claims", nil)
		return
	}

	userID := authClaims.UserID

	// 检查约束条件
	constraints, err := c.platformSwitchService.CheckSwitchConstraints(ctx, userID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "check_constraints_failed", err)
		return
	}

	// 构建响应
	response := &models.PlatformSwitchCheckResponse{
		CanSwitch:   constraints.CanSwitch,
		Constraints: *constraints,
	}

	if !constraints.CanSwitch {
		response.Reason = &constraints.Reason
	}

	common.Success(ctx, response)
}

// ExecutePlatformSwitch 执行平台切换
// @Summary 执行平台切换
// @Description 执行用户平台切换操作
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param request body models.PlatformSwitchRequest true "平台切换请求"
// @Success 200 {object} models.PlatformSwitchResponse
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/platform/switch/execute [post]
func (c *PlatformSwitchController) ExecutePlatformSwitch(ctx *gin.Context) {
	// 获取当前用户ID
	claims, exists := ctx.Get("claims")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "invalid_token_claims", nil)
		return
	}

	userID := authClaims.UserID

	// 解析请求参数
	var req models.PlatformSwitchRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_params", err)
		return
	}

	// 验证目标平台是否支持
	if !models.IsSupportedPlatform(req.TargetPlatform) {
		common.Error(ctx, http.StatusBadRequest, "platform_not_supported", nil)
		return
	}

	// 验证确认标志
	if !req.Confirm {
		common.Error(ctx, http.StatusBadRequest, "confirmation_required", nil)
		return
	}

	// 执行平台切换
	response, err := c.platformSwitchService.ExecutePlatformSwitch(ctx, userID, req.TargetPlatform, req.Reason, nil)
	if err != nil {
		// 检查是否是约束违反错误
		if err.Error() == "无法切换平台" {
			common.Error(ctx, http.StatusBadRequest, "platform_switch_constraint_violation", nil)
			return
		}
		common.Error(ctx, http.StatusInternalServerError, "platform_switch_failed", err)
		return
	}

	common.Success(ctx, response)
}

// 定义简化的返回结构体
type PlatformSwitchLogSimple struct {
	ID          int64  `json:"id"`
	UserID      int64  `json:"user_id"`
	OldPlatform string `json:"old_platform"`
	NewPlatform string `json:"new_platform"`
	SwitchTime  string `json:"switch_time"`
	Reason      string `json:"reason"`
	ExecutedBy  string `json:"executed_by"`
	CreatedAt   string `json:"created_at"`
}

// GetSwitchLogs 获取平台切换日志
// @Summary 获取平台切换日志
// @Description 获取用户的平台切换历史记录
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页大小" default(10)
// @Success 200 {object} common.SuccessResponse{data=[]PlatformSwitchLogSimple}
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/platform/switch/logs [get]
func (c *PlatformSwitchController) GetSwitchLogs(ctx *gin.Context) {
	// 获取当前用户ID
	claims, exists := ctx.Get("claims")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "invalid_token_claims", nil)
		return
	}

	userID := authClaims.UserID

	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 验证分页参数
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 10
	}

	// 获取切换日志
	logs, total, err := c.platformSwitchService.GetSwitchLogs(ctx, userID, page, pageSize)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_switch_logs_failed", err)
		return
	}

	// 在GetSwitchLogs和AdminGetUserSwitchLogs中转换logs
	var simpleLogs []PlatformSwitchLogSimple
	for _, log := range logs {
		executedBy := ""
		if log.Operator.Username != "" {
			executedBy = log.Operator.Username
		} else if log.OperatorID != nil {
			executedBy = strconv.FormatInt(*log.OperatorID, 10)
		}
		reason := ""
		if log.SwitchReason != nil {
			reason = *log.SwitchReason
		}
		simpleLogs = append(simpleLogs, PlatformSwitchLogSimple{
			ID:          log.ID,
			UserID:      log.UserID,
			OldPlatform: log.OldPlatform,
			NewPlatform: log.NewPlatform,
			SwitchTime:  log.CreatedAt.Format(time.RFC3339),
			Reason:      reason,
			ExecutedBy:  executedBy,
			CreatedAt:   log.CreatedAt.Format(time.RFC3339),
		})
	}

	common.Success(ctx, gin.H{
		"total":     total,
		"page":      page,
		"page_size": pageSize,
		"logs":      simpleLogs,
	})
}

// GetUserPlatformAccounts 获取用户的所有平台账户状态
// @Summary 获取用户平台账户状态
// @Description 获取用户在所有平台的矩阵账户状态
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Success 200 {object} common.SuccessResponse{data=[]models.UserMatrixAccount}
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/platform/switch/accounts [get]
func (c *PlatformSwitchController) GetUserPlatformAccounts(ctx *gin.Context) {
	// 获取当前用户ID
	claims, exists := ctx.Get("claims")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "invalid_token_claims", nil)
		return
	}

	userID := authClaims.UserID

	// 获取用户的所有平台账户
	accounts, err := c.platformSwitchService.GetUserPlatformAccounts(ctx, userID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_user_platform_accounts_failed", err)
		return
	}

	common.Success(ctx, accounts)
}

// AdminGetUserPlatformAccounts 管理员获取用户平台账户状态
// @Summary 管理员获取用户平台账户状态
// @Description 管理员获取指定用户在所有平台的矩阵账户状态
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param user_id path int true "用户ID"
// @Success 200 {object} common.SuccessResponse{data=[]models.UserMatrixAccount}
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 403 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/admin/platform/switch/accounts/{user_id} [get]
func (c *PlatformSwitchController) AdminGetUserPlatformAccounts(ctx *gin.Context) {
	// 获取用户ID参数
	userIDStr := ctx.Param("user_id")
	userID, err := strconv.ParseInt(userIDStr, 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_user_id", err)
		return
	}

	// 检查用户是否存在
	var user models.User
	if err := c.db.Where("id = ?", userID).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "user_not_found", nil)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "get_user_failed", err)
		}
		return
	}

	// 获取用户的所有平台账户
	accounts, err := c.platformSwitchService.GetUserPlatformAccounts(ctx, userID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_user_platform_accounts_failed", err)
		return
	}

	common.Success(ctx, accounts)
}

// AdminGetUserSwitchLogs 管理员获取用户平台切换日志
// @Summary 管理员获取用户平台切换日志
// @Description 管理员获取指定用户的平台切换历史记录
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param user_id path int true "用户ID"
// @Param page query int false "页码" default(1)
// @Param page_size query int false "每页大小" default(10)
// @Success 200 {object} common.SuccessResponse{data=[]PlatformSwitchLogSimple}
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 403 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/admin/platform/switch/logs/{user_id} [get]
func (c *PlatformSwitchController) AdminGetUserSwitchLogs(ctx *gin.Context) {
	// 获取用户ID参数
	userIDStr := ctx.Param("user_id")
	userID, err := strconv.ParseInt(userIDStr, 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_user_id", err)
		return
	}

	// 检查用户是否存在
	var user models.User
	if err := c.db.Where("id = ?", userID).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "user_not_found", nil)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "get_user_failed", err)
		}
		return
	}

	// 获取分页参数
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("page_size", "10"))

	// 验证分页参数
	if page < 1 {
		page = 1
	}
	if pageSize < 1 || pageSize > 100 {
		pageSize = 10
	}

	// 获取切换日志
	logs, total, err := c.platformSwitchService.GetSwitchLogs(ctx, userID, page, pageSize)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "get_switch_logs_failed", err)
		return
	}

	// 在GetSwitchLogs和AdminGetUserSwitchLogs中转换logs
	var simpleLogs []PlatformSwitchLogSimple
	for _, log := range logs {
		executedBy := ""
		if log.Operator.Username != "" {
			executedBy = log.Operator.Username
		} else if log.OperatorID != nil {
			executedBy = strconv.FormatInt(*log.OperatorID, 10)
		}
		reason := ""
		if log.SwitchReason != nil {
			reason = *log.SwitchReason
		}
		simpleLogs = append(simpleLogs, PlatformSwitchLogSimple{
			ID:          log.ID,
			UserID:      log.UserID,
			OldPlatform: log.OldPlatform,
			NewPlatform: log.NewPlatform,
			SwitchTime:  log.CreatedAt.Format(time.RFC3339),
			Reason:      reason,
			ExecutedBy:  executedBy,
			CreatedAt:   log.CreatedAt.Format(time.RFC3339),
		})
	}

	common.Success(ctx, gin.H{
		"total":     total,
		"page":      page,
		"page_size": pageSize,
		"logs":      simpleLogs,
	})
}

// AdminCheckUserSwitchConstraints 管理员检查用户平台切换约束
// @Summary 管理员检查用户平台切换约束
// @Description 管理员检查指定用户的平台切换约束
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param user_id path int true "用户ID"
// @Success 200 {object} models.PlatformSwitchCheckResponse
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 403 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/admin/platform/switch/check/{user_id} [get]
func (c *PlatformSwitchController) AdminCheckUserSwitchConstraints(ctx *gin.Context) {
	// 获取用户ID参数
	userIDStr := ctx.Param("user_id")
	userID, err := strconv.ParseInt(userIDStr, 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_user_id", err)
		return
	}

	// 检查用户是否存在
	var user models.User
	if err := c.db.Where("id = ?", userID).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "user_not_found", nil)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "get_user_failed", err)
		}
		return
	}

	// 检查约束条件
	constraints, err := c.platformSwitchService.CheckSwitchConstraints(ctx, userID)
	if err != nil {
		common.Error(ctx, http.StatusInternalServerError, "check_constraints_failed", err)
		return
	}

	// 构建响应
	response := &models.PlatformSwitchCheckResponse{
		CanSwitch:   constraints.CanSwitch,
		Constraints: *constraints,
	}

	if !constraints.CanSwitch {
		response.Reason = &constraints.Reason
	}

	common.Success(ctx, response)
}

// AdminExecuteUserPlatformSwitch 管理员执行用户平台切换
// @Summary 管理员执行用户平台切换
// @Description 管理员为指定用户执行平台切换操作
// @Tags 平台切换
// @Accept json
// @Produce json
// @Security BearerAuth
// @Param user_id path int true "用户ID"
// @Param request body models.PlatformSwitchRequest true "平台切换请求"
// @Success 200 {object} models.PlatformSwitchResponse
// @Failure 400 {object} common.ErrorResponse
// @Failure 401 {object} common.ErrorResponse
// @Failure 403 {object} common.ErrorResponse
// @Failure 500 {object} common.ErrorResponse
// @Router /api/admin/platform/switch/execute/{user_id} [post]
func (c *PlatformSwitchController) AdminExecuteUserPlatformSwitch(ctx *gin.Context) {
	// 获取当前管理员ID
	claims, exists := ctx.Get("claims")
	if !exists {
		common.Error(ctx, http.StatusUnauthorized, "unauthorized", nil)
		return
	}

	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		common.Error(ctx, http.StatusInternalServerError, "invalid_token_claims", nil)
		return
	}

	operatorID := authClaims.UserID

	// 获取用户ID参数
	userIDStr := ctx.Param("user_id")
	userID, err := strconv.ParseInt(userIDStr, 10, 64)
	if err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_user_id", err)
		return
	}

	// 解析请求参数
	var req models.PlatformSwitchRequest
	if err := ctx.ShouldBindJSON(&req); err != nil {
		common.Error(ctx, http.StatusBadRequest, "invalid_request_params", err)
		return
	}

	// 验证目标平台是否支持
	if !models.IsSupportedPlatform(req.TargetPlatform) {
		common.Error(ctx, http.StatusBadRequest, "platform_not_supported", nil)
		return
	}

	// 验证确认标志
	if !req.Confirm {
		common.Error(ctx, http.StatusBadRequest, "confirmation_required", nil)
		return
	}

	// 检查用户是否存在
	var user models.User
	if err := c.db.Where("id = ?", userID).First(&user).Error; err != nil {
		if err == gorm.ErrRecordNotFound {
			common.Error(ctx, http.StatusNotFound, "user_not_found", nil)
		} else {
			common.Error(ctx, http.StatusInternalServerError, "get_user_failed", err)
		}
		return
	}

	// 执行平台切换
	response, err := c.platformSwitchService.ExecutePlatformSwitch(ctx, userID, req.TargetPlatform, req.Reason, &operatorID)
	if err != nil {
		// 检查是否是约束违反错误
		if err.Error() == "无法切换平台" {
			common.Error(ctx, http.StatusBadRequest, "platform_switch_constraint_violation", nil)
			return
		}
		common.Error(ctx, http.StatusInternalServerError, "platform_switch_failed", err)
		return
	}

	common.Success(ctx, response)
}
